package com.hitqz.robot.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hitqz.robot.api.business.dto.*;
import com.hitqz.robot.api.business.model.vo.form.FormFieldConfigModalVo;
import com.hitqz.robot.api.common.entity.*;
import com.hitqz.robot.api.dispatch.model.MessageDto;
import com.hitqz.robot.api.dispatch.protocol.ProtocolEnum;
import com.hitqz.robot.api.dispatch.protocol.dto.FormConfigModalDto;
import com.hitqz.robot.api.dispatch.protocol.dto.FormFieldConfigModalDto;
import com.hitqz.robot.biz.mapper.PatrolDevMapper;
import com.hitqz.robot.biz.service.*;
import com.hitqz.robot.netty.ChannelCache;
import com.hitqz.robot.netty.service.impl.Send2ServerServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wengyx
 * @date 2024/8/7
 */
@Service
@AllArgsConstructor
public class PatrolDevServiceIml extends ServiceImpl<PatrolDevMapper, PatrolDev> implements PatrolDevService {

    private final Send2ServerServiceImpl send2ServerService;
    private final RobotService robotService;
    private final PatrolCheckTypeService patrolCheckTypeService;
    private final PatrolObjectService patrolObjectService;
    private final PatrolPosPoseGroupService patrolPosPoseGroupService;
    private final PatrolItemService patrolItemService;

    @Override
    public List<Tree<Long>> selectTree(String name) {
        // 查询所有设备
        List<PatrolDev> list = list();
        if (list.isEmpty()) {
            PatrolDev patrolDev = new PatrolDev();
            patrolDev.setName("默认节点");
            patrolDev.setParentId(0);
            patrolDev.setIsParent(1);
            save(patrolDev);
        }

        // 按 parentId 分组
        Map<Integer, List<PatrolDev>> map = list.stream()
                .collect(Collectors.groupingBy(PatrolDev::getParentId));

        List<TreeNode<Long>> collect = list.stream()
                .filter(dev -> Objects.equals(dev.getIsParent(), 1))
                .map(dev -> {
                    TreeNode<Long> treeNode = new TreeNode<>();
                    treeNode.setId(dev.getId());
                    treeNode.setParentId(0L);
                    treeNode.setName(dev.getName());
                    treeNode.setWeight(dev.getId());

                    Map<String, Object> extra = new HashMap<>(8);
                    List<PatrolDev> patrolDevs = Optional.ofNullable(map.get(dev.getId().intValue()))
                            .orElse(new ArrayList<>());

                    // 二级子节点
                    List<TreeNode<Long>> childrenNode = patrolDevs.stream()
                            .map(f -> {
                                TreeNode<Long> children = new TreeNode<>();
                                children.setId(Long.valueOf(f.getId()));
                                children.setParentId((long) f.getParentId());
                                children.setName(f.getName());
                                children.setWeight(f.getId());
                                return children;
                            })
                            .collect(Collectors.toList());

                    // 如果有 name 条件，进行过滤
                    if (StrUtil.isNotBlank(name)) {
                        childrenNode = childrenNode.stream()
                                .filter(c -> c.getName() != null && c.getName().toString().contains(name))
                                .collect(Collectors.toList());

                        // 如果过滤后子节点为空，则整个父节点不需要保留
                        if (childrenNode.isEmpty()) return null;
                    }

                    extra.put("children", childrenNode);
                    treeNode.setExtra(extra);
                    return treeNode;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return TreeUtil.build(collect, 0L);
    }

    @Override
    public void syncDev() {
        Robot robot = robotService.getDefaultRobot();
        List<PatrolDev> devList = list();
        List<PatrolCheckType> checkTypes = patrolCheckTypeService.list();
        List<PatrolObject> objects = patrolObjectService.list();
        List<PatrolPosPoseGroup> posPoseGroups = patrolPosPoseGroupService.list();
        List<PatrolItem> items = patrolItemService.list();
        List<PatrolDevDto> patrolDevDtos = BeanUtil.copyToList(devList, PatrolDevDto.class);
        List<PatrolCheckTypeDto> patrolCheckTypeDtos = BeanUtil.copyToList(checkTypes, PatrolCheckTypeDto.class);
        List<PatrolObjectDto> patrolObjectDtos = BeanUtil.copyToList(objects, PatrolObjectDto.class);
        List<PatrolPosPoseGroupDto> patrolPosPoseGroupDtos = BeanUtil.copyToList(posPoseGroups, PatrolPosPoseGroupDto.class);
        List<PatrolItemDto> patrolItemDtos = BeanUtil.copyToList(items, PatrolItemDto.class);
        PatrolConfigInfo patrolConfigInfo = new PatrolConfigInfo(robot.getRobotSn(),patrolDevDtos,patrolCheckTypeDtos , patrolObjectDtos,patrolPosPoseGroupDtos,patrolItemDtos);
        send2ServerService.syncPatrolInfo(robot,patrolConfigInfo);
    }
}
